using System;
using System.IO;
using System.Net;
using System.Text;
using System.Web;
using System.Collections.Generic;
using System.Collections;
using System.Xml.Serialization;
using AandEDLL.DataAccess;

namespace AandEDLL.ItemSearchAPI
{
    /// <summary>
    /// YahooSearchService wrappes calls to the Yahoo Web Service.
    /// </summary>
    public class YahooSearchService : SearchService
    {
        public override void initializeService()
        {
            return;
        }
        public override List<Item> search(String query)
        {
            List<Item> searchResults = new List<Item>();

            string appId = "SfMTpJjV34GC3TtaU3SEwuM6Q4wOs2NTVk7BNXLcfifajQcPxqn1E_3H8KZY151cuGqgRhw-";
            string requestUri = String.Format("http://api.shopping.yahoo.com/ShoppingService/V1/productSearch?appid={0}&query={1}&results=50", appId, HttpUtility.UrlEncode(query, Encoding.UTF8));

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);

            ResultSet resultSet = null;
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(ResultSet));
                    resultSet = (ResultSet)serializer.Deserialize(responseStream);
                }
            }
            if (resultSet.Result != null)
            {
                foreach (YahooSearchService.ResultType result in resultSet.Result)
                {
                    if (result.Offer != null)
                    {
                        Item item = new Item();
                        String name = result.Offer[0].ProductName;
                        String desc = result.Offer[0].Summary;
                        String url = result.Offer[0].Url;

                        item.ItemName = name;
                        item.Description = desc;
                        item.Price = result.Offer[0].Price;
                        item.URL = url;
                        item.SearchDate = DateTime.Now;
                        item.Source = "YAHOO";
                        searchResults.Add(item);
                    } //end if       
                    //A catalog contains many offers from different merchants with the same product
                    //we must do another web service call to yahoo to look up the items in the catalog
                    else if (result.Catalog != null)
                    {
                        CatalogListing catalogList = ListCatalog(result.Catalog[0].ID);
                        for (int j = 0; j < Convert.ToInt32(catalogList.numOffers); j++)
                        {
                            Item item = new Item();
                            String name = result.Catalog[0].ProductName;
                            String desc = result.Catalog[0].Summary;
                            String url = catalogList.Offer[j].Url;

                            item.ItemName = name;
                            item.Description = desc;
                            item.Price = catalogList.Offer[j].BasePrice;
                            item.URL = url;
                            item.SearchDate = DateTime.Now;
                            item.Source = "YAHOO";
                            searchResults.Add(item);
                        }
                    }
                } //end foreach 
            } //end if   

            return searchResults;
        }

        public CatalogListing ListCatalog(string catalogid)
        {
            string appId = "SfMTpJjV34GC3TtaU3SEwuM6Q4wOs2NTVk7BNXLcfifajQcPxqn1E_3H8KZY151cuGqgRhw-";
            string requestUri = String.Format("http://api.shopping.yahoo.com/ShoppingService/V1/catalogListing?appid={0}&catalogid={1}", appId, HttpUtility.UrlEncode(catalogid, Encoding.UTF8));

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);

            CatalogListing catalogList = null;
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(CatalogListing));
                    catalogList = (CatalogListing)serializer.Deserialize(responseStream);
                }
            }

            return catalogList;
        }




        //------------------------------------------------------------------------------
        // <auto-generated>
        //     This code was generated by a tool.
        //     Runtime Version:2.0.50727.42
        //
        //     Changes to this file may cause incorrect behavior and will be lost if
        //     the code is regenerated.
        // </auto-generated>
        //------------------------------------------------------------------------------

        // 
        // This source code was auto-generated by xsd, Version=2.0.50727.42.
        // 




        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:prods")]
        [System.Xml.Serialization.XmlRootAttribute("Thumbnail", Namespace = "urn:yahoo:prods", IsNullable = false)]
        public partial class ThumbnailType
        {

            private string urlField;

            private string heightField;

            private string widthField;

            /// <remarks/>
            public string Url
            {
                get
                {
                    return this.urlField;
                }
                set
                {
                    this.urlField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(DataType = "nonNegativeInteger")]
            public string Height
            {
                get
                {
                    return this.heightField;
                }
                set
                {
                    this.heightField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(DataType = "nonNegativeInteger")]
            public string Width
            {
                get
                {
                    return this.widthField;
                }
                set
                {
                    this.widthField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:prods")]
        public partial class MerchantType
        {

            private string nameField;

            private string idField;

            /// <remarks/>
            public string Name
            {
                get
                {
                    return this.nameField;
                }
                set
                {
                    this.nameField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "nonNegativeInteger")]
            public string ID
            {
                get
                {
                    return this.idField;
                }
                set
                {
                    this.idField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:prods")]
        public partial class OfferType
        {

            private string urlField;

            private string productNameField;

            private decimal priceField;

            private string summaryField;

            private ThumbnailType[] thumbnailField;

            private MerchantType[] merchantField;

            /// <remarks/>
            public string Url
            {
                get
                {
                    return this.urlField;
                }
                set
                {
                    this.urlField = value;
                }
            }

            /// <remarks/>
            public string ProductName
            {
                get
                {
                    return this.productNameField;
                }
                set
                {
                    this.productNameField = value;
                }
            }

            /// <remarks/>
            public decimal Price
            {
                get
                {
                    return this.priceField;
                }
                set
                {
                    this.priceField = value;
                }
            }

            /// <remarks/>
            public string Summary
            {
                get
                {
                    return this.summaryField;
                }
                set
                {
                    this.summaryField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("Thumbnail")]
            public ThumbnailType[] Thumbnail
            {
                get
                {
                    return this.thumbnailField;
                }
                set
                {
                    this.thumbnailField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("Merchant")]
            public MerchantType[] Merchant
            {
                get
                {
                    return this.merchantField;
                }
                set
                {
                    this.merchantField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:prods")]
        public partial class SpecificationType
        {

            private string specificationLabelField;

            private string specificationValueField;

            /// <remarks/>
            public string SpecificationLabel
            {
                get
                {
                    return this.specificationLabelField;
                }
                set
                {
                    this.specificationLabelField = value;
                }
            }

            /// <remarks/>
            public string SpecificationValue
            {
                get
                {
                    return this.specificationValueField;
                }
                set
                {
                    this.specificationValueField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:prods")]
        public partial class UserRatingType
        {

            private decimal maxRatingField;

            private string numRatingsField;

            private decimal averageRatingField;

            private string ratingUrlField;

            private string createRatingUrlField;

            /// <remarks/>
            public decimal MaxRating
            {
                get
                {
                    return this.maxRatingField;
                }
                set
                {
                    this.maxRatingField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute(DataType = "nonNegativeInteger")]
            public string NumRatings
            {
                get
                {
                    return this.numRatingsField;
                }
                set
                {
                    this.numRatingsField = value;
                }
            }

            /// <remarks/>
            public decimal AverageRating
            {
                get
                {
                    return this.averageRatingField;
                }
                set
                {
                    this.averageRatingField = value;
                }
            }

            /// <remarks/>
            public string RatingUrl
            {
                get
                {
                    return this.ratingUrlField;
                }
                set
                {
                    this.ratingUrlField = value;
                }
            }

            /// <remarks/>
            public string CreateRatingUrl
            {
                get
                {
                    return this.createRatingUrlField;
                }
                set
                {
                    this.createRatingUrlField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:prods")]
        public partial class CatalogType
        {

            private string urlField;

            private string productNameField;

            private decimal priceFromField;

            private decimal priceToField;

            private bool priceToFieldSpecified;

            private string descriptionField;

            private string summaryField;

            private ThumbnailType[] thumbnailField;

            private UserRatingType[] userRatingField;

            // private SpecificationType[][] specificationListField;

            private string idField;

            /// <remarks/>
            public string Url
            {
                get
                {
                    return this.urlField;
                }
                set
                {
                    this.urlField = value;
                }
            }

            /// <remarks/>
            public string ProductName
            {
                get
                {
                    return this.productNameField;
                }
                set
                {
                    this.productNameField = value;
                }
            }

            /// <remarks/>
            public decimal PriceFrom
            {
                get
                {
                    return this.priceFromField;
                }
                set
                {
                    this.priceFromField = value;
                }
            }

            /// <remarks/>
            public decimal PriceTo
            {
                get
                {
                    return this.priceToField;
                }
                set
                {
                    this.priceToField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlIgnoreAttribute()]
            public bool PriceToSpecified
            {
                get
                {
                    return this.priceToFieldSpecified;
                }
                set
                {
                    this.priceToFieldSpecified = value;
                }
            }

            /// <remarks/>
            public string Description
            {
                get
                {
                    return this.descriptionField;
                }
                set
                {
                    this.descriptionField = value;
                }
            }

            /// <remarks/>
            public string Summary
            {
                get
                {
                    return this.summaryField;
                }
                set
                {
                    this.summaryField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("Thumbnail")]
            public ThumbnailType[] Thumbnail
            {
                get
                {
                    return this.thumbnailField;
                }
                set
                {
                    this.thumbnailField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("UserRating")]
            public UserRatingType[] UserRating
            {
                get
                {
                    return this.userRatingField;
                }
                set
                {
                    this.userRatingField = value;
                }
            }

            /// <remarks/>
            /*       [System.Xml.Serialization.XmlArrayItemAttribute("Specification", typeof(SpecificationType), IsNullable=false)]
                public SpecificationType[][] SpecificationList {
                    get {
                        return this.specificationListField;
                    }
                    set {
                        this.specificationListField = value;
                    }
                }*/

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "nonNegativeInteger")]
            public string ID
            {
                get
                {
                    return this.idField;
                }
                set
                {
                    this.idField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:prods")]
        public partial class ResultType
        {

            private CatalogType[] catalogField;

            private OfferType[] offerField;

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("Catalog")]
            public CatalogType[] Catalog
            {
                get
                {
                    return this.catalogField;
                }
                set
                {
                    this.catalogField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("Offer")]
            public OfferType[] Offer
            {
                get
                {
                    return this.offerField;
                }
                set
                {
                    this.offerField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:yahoo:prods", IsNullable = false)]
        public partial class ResultSet
        {

            private ResultType[] resultField;

            private string totalResultsAvailableField;

            private string totalResultsReturnedField;

            private string firstResultPositionField;

            private string spellSuggestionField;

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("Result")]
            public ResultType[] Result
            {
                get
                {
                    return this.resultField;
                }
                set
                {
                    this.resultField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "integer")]
            public string totalResultsAvailable
            {
                get
                {
                    return this.totalResultsAvailableField;
                }
                set
                {
                    this.totalResultsAvailableField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "integer")]
            public string totalResultsReturned
            {
                get
                {
                    return this.totalResultsReturnedField;
                }
                set
                {
                    this.totalResultsReturnedField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "integer")]
            public string firstResultPosition
            {
                get
                {
                    return this.firstResultPositionField;
                }
                set
                {
                    this.firstResultPositionField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string spellSuggestion
            {
                get
                {
                    return this.spellSuggestionField;
                }
                set
                {
                    this.spellSuggestionField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:yahoo:prods", IsNullable = false)]
        public partial class NewDataSet
        {

            private object[] itemsField;

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("ResultSet", typeof(ResultSet))]
            [System.Xml.Serialization.XmlElementAttribute("Thumbnail", typeof(ThumbnailType))]
            public object[] Items
            {
                get
                {
                    return this.itemsField;
                }
                set
                {
                    this.itemsField = value;
                }
            }
        }

        //------------------------------------------------------------------------------
        // <auto-generated>
        //     This code was generated by a tool.
        //     Runtime Version:2.0.50727.42
        //
        //     Changes to this file may cause incorrect behavior and will be lost if
        //     the code is regenerated.
        // </auto-generated>
        //------------------------------------------------------------------------------

        // 
        // This source code was auto-generated by xsd, Version=2.0.50727.42.
        // 


        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
        [System.Xml.Serialization.XmlRootAttribute(Namespace = "urn:yahoo:merchoffers", IsNullable = false)]
        public partial class CatalogListing
        {

            private CatalogOfferType[] offerField;

            private string idField;

            private string numOffersField;

            private string zipField;

            private string numDisplayedField;

            private string startingIndexField;

            /// <remarks/>
            [System.Xml.Serialization.XmlElementAttribute("Offer")]
            public CatalogOfferType[] Offer
            {
                get
                {
                    return this.offerField;
                }
                set
                {
                    this.offerField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "integer")]
            public string ID
            {
                get
                {
                    return this.idField;
                }
                set
                {
                    this.idField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "integer")]
            public string numOffers
            {
                get
                {
                    return this.numOffersField;
                }
                set
                {
                    this.numOffersField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute()]
            public string zip
            {
                get
                {
                    return this.zipField;
                }
                set
                {
                    this.zipField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "integer")]
            public string numDisplayed
            {
                get
                {
                    return this.numDisplayedField;
                }
                set
                {
                    this.numDisplayedField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "integer")]
            public string startingIndex
            {
                get
                {
                    return this.startingIndexField;
                }
                set
                {
                    this.startingIndexField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:merchoffers")]
        public partial class CatalogOfferType
        {

            private MerchantType merchantField;

            private string urlField;

            private ConditionType conditionField;

            private bool conditionFieldSpecified;

            private string taxCostField;

            private string shippingCostField;

            private decimal basePriceField;

            private decimal totalPriceField;

            private decimal strikeThroughPriceField;

            private bool strikeThroughPriceFieldSpecified;

            /// <remarks/>
            public MerchantType Merchant
            {
                get
                {
                    return this.merchantField;
                }
                set
                {
                    this.merchantField = value;
                }
            }

            /// <remarks/>
            public string Url
            {
                get
                {
                    return this.urlField;
                }
                set
                {
                    this.urlField = value;
                }
            }

            /// <remarks/>
            public ConditionType Condition
            {
                get
                {
                    return this.conditionField;
                }
                set
                {
                    this.conditionField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlIgnoreAttribute()]
            public bool ConditionSpecified
            {
                get
                {
                    return this.conditionFieldSpecified;
                }
                set
                {
                    this.conditionFieldSpecified = value;
                }
            }

            /// <remarks/>
            public string TaxCost
            {
                get
                {
                    return this.taxCostField;
                }
                set
                {
                    this.taxCostField = value;
                }
            }

            /// <remarks/>
            public string ShippingCost
            {
                get
                {
                    return this.shippingCostField;
                }
                set
                {
                    this.shippingCostField = value;
                }
            }

            /// <remarks/>
            public decimal BasePrice
            {
                get
                {
                    return this.basePriceField;
                }
                set
                {
                    this.basePriceField = value;
                }
            }

            /// <remarks/>
            public decimal TotalPrice
            {
                get
                {
                    return this.totalPriceField;
                }
                set
                {
                    this.totalPriceField = value;
                }
            }

            /// <remarks/>
            public decimal StrikeThroughPrice
            {
                get
                {
                    return this.strikeThroughPriceField;
                }
                set
                {
                    this.strikeThroughPriceField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlIgnoreAttribute()]
            public bool StrikeThroughPriceSpecified
            {
                get
                {
                    return this.strikeThroughPriceFieldSpecified;
                }
                set
                {
                    this.strikeThroughPriceFieldSpecified = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Diagnostics.DebuggerStepThroughAttribute()]
        [System.ComponentModel.DesignerCategoryAttribute("code")]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:merchoffers")]
        public partial class CatalogMerchantType
        {

            private string nameField;

            private string idField;

            /// <remarks/>
            public string Name
            {
                get
                {
                    return this.nameField;
                }
                set
                {
                    this.nameField = value;
                }
            }

            /// <remarks/>
            [System.Xml.Serialization.XmlAttributeAttribute(DataType = "nonNegativeInteger")]
            public string ID
            {
                get
                {
                    return this.idField;
                }
                set
                {
                    this.idField = value;
                }
            }
        }

        /// <remarks/>
        [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
        [System.SerializableAttribute()]
        [System.Xml.Serialization.XmlTypeAttribute(Namespace = "urn:yahoo:merchoffers")]
        public enum ConditionType
        {

            /// <remarks/>
            @new,

            /// <remarks/>
            refurbished,

            /// <remarks/>
            [System.Xml.Serialization.XmlEnumAttribute("merchant-marketplace")]
            merchantmarketplace,
        }
    }
}